/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package io.netty.channel;

/**
 * {@link ChannelHandler} which adds callbacks for state changes. This allows the user
 * to hook in to state changes easily.
 * 入站处理器
 * 入站处理触发的方向为：自底向上，Netty的内部（如通道）到ChannelInboundHandler入站处理器。
 */
public interface ChannelInboundHandler extends ChannelHandler {

    /**
     * The {@link Channel} of the {@link ChannelHandlerContext} was registered with its {@link EventLoop}
     * 当通道注册完成后，Netty会调用fireChannelRegistered方法，触发通道注册事件。而在
     * 通道流水线注册过的入站处理器Handler的channelRegistered回调方法，将会被调用到。
     */
    void channelRegistered(ChannelHandlerContext ctx) throws Exception;

    /**
     * The {@link Channel} of the {@link ChannelHandlerContext} was unregistered from its {@link EventLoop}
     */
    void channelUnregistered(ChannelHandlerContext ctx) throws Exception;

    /**
     * The {@link Channel} of the {@link ChannelHandlerContext} is now active
     * 当通道激活完成后，Netty 会调用 fireChannelActive方法，触发通道激活事件。而在通道
     * 流水线注册过的入站处理器的 channelActive 回调方法，会被调用到。
     */
    void channelActive(ChannelHandlerContext ctx) throws Exception;

    /**
     * The {@link Channel} of the {@link ChannelHandlerContext} was registered is now inactive and reached its
     * end of lifetime.
     * 当连接被断开或者不可用时，Netty 会调用 fireChannelInactive ，触发连接不可用事件。
     * 而在通道流水线注册过的入站处理器的 channelInactive 回调方法，会被调用到。
     */
    void channelInactive(ChannelHandlerContext ctx) throws Exception;

    /**
     * Invoked when the current {@link Channel} has read a message from the peer.
     * 当通道缓冲区可读，Netty 的反应器完成数据读取后， 会调用 fireChannelRead 发射读取到
     * 的二进制数据 。而在通道流水线注册过的入站处理器的 channelRead 回调方法，会被调用到，
     * 以便完成入站数据的读取和处理。
     *
     * 真正执行底层读数据 。入站read处理在完成 Netty 通道从Java IO 通道的数据读取 后， 再 把数据发射到通道的 pipeline 最后数据会 依次进入 pipeline 的
     * 各个入站处理器 最终被 入站处理器的 channelRead 方法 处理 。
     */
    void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception;

    /**
     * Invoked when the last message read by the current read operation has been consumed by
     * {@link #channelRead(ChannelHandlerContext, Object)}.  If {@link ChannelOption#AUTO_READ} is off, no further
     * attempt to read an inbound data from the current {@link Channel} will be made until
     * {@link ChannelHandlerContext#read()} is called.
     * 当通道缓冲区读完，Netty 会调用 fireChannelReadComplete ，触发通道缓冲区读完事件。
     * 而在通道流水线注册过的入站处理器的 channelReadComplete 回调方法，会被调用到。
     */
    void channelReadComplete(ChannelHandlerContext ctx) throws Exception;

    /**
     * Gets called if an user event was triggered.
     */
    void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception;

    /**
     * Gets called once the writable state of a {@link Channel} changed. You can check the state with
     * {@link Channel#isWritable()}.
     */
    void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception;

    /**
     * Gets called if a {@link Throwable} was thrown.
     * 当通道处理过程发生异常时，
     * Netty 会调用 fireExceptionCaught ，触发异常捕获事件。而
     * 在通道流水线注册过的入站处理器的 exceptio nCaught 方法，会被调用到。注意，这个方法是
     * 在通道处理器中 ChannelHandler 定义的方法，入站处理器、出站处理器接口都继承到了该方
     * 法。
     */
    @Override
    @SuppressWarnings("deprecation")
    void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
}
